home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-21 | 38.5 KB | 969 lines | [TEXT/pdos] |
- Apple II
- Technical Notes
- _____________________________________________________________________________
- Developer Technical Support
-
- Apple IIgs
- #35: Printer Driver Specifications
-
- Revised by: Matt Deatherage September 1990
- Written by: Dan Hitchens, Matt Deatherage & Suki Lee May 1988
-
- This Technical Note describes the routines and internal structures needed to
- design a printer driver for the Apple IIgs system, and you should use this
- Note with the Apple IIgs Toolbox Reference manuals. An overview and
- associated parameters for each of the printer driver routines are in the Print
- Manager chapter, and you should refer to these for a complete picture.
- Changed since March 1990: Added corrections and further descriptions.
- _____________________________________________________________________________
-
-
- Printing Modes
-
- There are two printing modes: immediate and deferred.
-
- o In immediate mode, pages are printed as they are drawn into the
- printing grafPort. As the application makes QuickDraw II calls,
- the printer driver immediately generates commands, transferring
- ink to page when the page is closed. This is the fastest form of
- printing, but only produces high-quality images on printers that
- can translate QuickDraw II commands to other graphic commands.
- For example, the LaserWriter driver translates the QuickDraw II
- calls into PostScript(R) calls which can produce high-quality
- images.
-
- o In deferred mode (sometimes referred to as spool mode), pages are
- captured to memory or disk and printed after all pages have been
- defined. Most printer drivers use deferred mode to create high-
- quality images. Since most drivers cannot obtain enough memory to
- image an entire page at once, they redraw page in several pieces,
- or bands. The printer driver creates a grafPort whose boundsRect,
- portRect, clipRgn, and visRgn correspond to the band and plays the
- picture back, thus causing the saved commands to draw only the
- images which fall within the band. Once the pixel image for the
- band is created, the printer driver converts the image to printer
- codes and sends the codes to the printer through the port driver.
-
-
- File Structure
-
- The user can install new printer drivers into the system by copying a printer
- driver file into a subdirectory called DRIVERS within the SYSTEM subdirectory.
- The printer driver file must be of type $BB and have an auxiliary type of
- $0001.
-
-
-
- Print Driver Calls
-
- A printer driver must support the following calls:
-
- PrDefault $0913 Sets print record to default
- PrValidate $0A13 Validates print record
- PrStlDialog $0B13 Performs a style dialog
- PrJobDialog $0C13 Performs a job dialog
- PrPixelMap $0D13 Prints a pixel map
- PrOpenDoc $0E13 Opens the document
- PrCloseDoc $0F13 Closes the document
- PrOpenPage $1013 Opens a page
- PrClosePage $1113 Closes a page
- PrPicFile $1213 Prints a picture file
- --RESERVED-- $1313
- PrError $1413 Gets the error value
- PrSetError $1513 Sets the error value
- GetDeviceName $1713 Gets device's name
- PrDriverVer $2313 Gets installed driver version
-
- Printer drivers may support the following calls if they use the new driver
- structure outlined below:
-
- PrGetPrinterSpecs $1813 Returns printer type and characteristics
- PrGetPgOrientation $3813 Returns page orientation
-
-
- Print Driver Entry
-
- o For older drivers, entry is at the first byte (no offset). For newer
- (Print Manager 3.0 and later) drivers, the first word is $0000, indicating
- a new style driver. The next word is a count of how many calls this driver
- supports. All drivers must support the minimum call set. Additional calls
- must be supported in the sequence listed (for example, if a driver supports
- PrGetPgOrientation, it must also support PrGetPrinterSpecs).
- o The Print Manager places an index to the correct routine in the X register
- (see the example and note the specific ordering of the routines) .
- o There are two long return addresses (six bytes) that have been pushed onto
- the stack. (You must take these addresses into account to access the
- parameters and to return correctly.)
-
- Example
-
- StartOfNewDriver START
-
- dc i2'0' ; new style driver
- dc i2'(ListEnd-PrDriverList)/4' ; count
-
- jmp (PrDriverList,x)
-
-
- PrDriverList dc a4'PrDefault'
- dc a4'PrValidate'
- dc a4'PrStlDialog'
- dc a4'PrJobDialog'
- dc a4'PrDriverVer'
- dc a4'PrOpenDoc'
- dc a4'PrCloseDoc'
- dc a4'PrOpenPage'
- dc a4'PrClosePage'
- dc a4'PrPicFile'
- dc a4'InvalidRoutine'
- dc a4'PrError'
- dc a4'PrSetError'
- dc a4'GetDeviceName'
- dc a4'PrPixelMap'
- dc a4'PrGetPrinterSpecs'
- dc a4'PrGetPgOrientation'
- ListEnd anop
-
- In previous versions of this Note, the PrPixelMap and PrDriverVer entries were
- reversed.
-
- Note that when using the above technique, you're using a 16-bit jump into a
- table of 24-bit addresses. If all your entry points are in the same segment,
- this is not a problem.
-
- If your routines' entry points are not all in the same segment, you need a
- dispatching routine like the following:
-
- StartOfNewDriver START
-
- dc i2 '0' ; new style driver
- dc i2 '(ListEnd-PrDriverList)/4' ; count
-
- lda PrDriverList+2,x
- sep #$20
- pha ; push high byte of
- ; address
- rep #$20
- lda PrDriverList,x
- dec a ; decrement low 2
- ; bytes only
- pha ; push modified low
- ; word of address
- rtl ; transfer to the
- ; routine
-
- See Apple IIgs Technical Note #90, 65816 Tips and Pitfalls, for a discussion
- of dispatching with RTL.
-
-
- Print Driver Exit
-
- When one of your routines is ready to exit, it needs to remove the input
- parameters from the stack, leaving the result space (if any) and the two RTL
- addresses. Set the accumulator and the carry flag to reflect any error you
- are returning, then perform an RTL.
-
-
- Example
-
- If there are N bytes of input parameters to remove, use something like the
- following. This code assumes that the error code is in the accumulator.
-
- tay ; keep error code in Y
- ; temporarily
- lda 5,s
- sta N+5,s
- lda 3,s
- sta N+3,s
- lda 1,s
- sta N+1,s
- tsc
- clc
- adc #N
- tcs
- tya ; get error code
- cmp #1 ; set carry if error
- ; is not zero
- rtl
-
- Figure 1 diagrams the stack just before exiting the print driver:
-
- |
- | Previous Contents
- |___________________
- |
- | Results (if any)
- |___________________
- |
- | RTL2 (3 bytes)
- |___________________
- |
- | RTL1 (3 bytes)
- |___________________
-
- <-- Stack Pointer
-
- Figure 1-Stack Prior to Exiting the Print Driver
-
- You should do an RTL with the contents of the flags and registers set
- appropriately. (See the Return from Call section of the "Using The Apple
- Tools" chapter of the Apple IIgs Toolbox Reference.)
-
-
- Print Record Structure
-
- Since application programs often need to fiddle with parts of the print record
- (i.e., the values in the style subrecord), we have defined ways for
- applications to interpret the print record, and specifically the style
- subrecord.
-
- iDev, the first word of the printer information subrecord, has two defined
- values for third-party printer drivers. A value of $8001 indicates a dot-
- matrix printer while a value of $8003 indicates a laser printer.
-
- A value of $8001 indicates that fields of the style subrecord should be
- interpreted as they are by the ImageWriter driver, as documented in the Apple
- IIgs Toolbox Reference. The first seven bits (0-6) of wDev are defined as for
- the ImageWriter driver. Bits 7-11 are reserved for Apple's use and must be
- set to zero. Bits 12-15 may be used by third-party printer drivers as
- necessary; these bits are set to zero in Apple's drivers.
-
- A value of $8003 indicates that fields of the style subrecord should be
- interpreted as they are by the LaserWriter driver. The first four bits (0-3)
- of wDev are defined as for the LaserWriter driver. Bits 4-11 are reserved for
- Apple's use and must be set to zero. Bits 12-15 may be used by third-party
- printer drivers as necessary; these bits are set to zero in Apple's drivers.
-
- If an application wishes to take advantages of specific features of a third-
- party printer driver, it has to know that it is dealing with that driver.
- Since all drivers look pretty much alike, the Print Manager allows you to ask
- for the name of the currently selected printer driver. An application may
- make the Print Manager call PMGetPrinterName, which is documented in Volume 3
- of the Toolbox Reference. The Print Manager returns the name of the currently
- selected printer in a Pascal (length byte) string. The name returned is the
- name of the file from which the driver was loaded. If you intend to use this
- method to identify a driver, you must inform users not to rename the Printer
- Driver file on the boot disk.
-
- For alternate driver identification, Developer Technical Support assigns new
- iDev values if you feel it is absolutely necessary for your driver. Please
- keep in mind, however, that no application knows how to interpret style
- records for non-standard iDev values, and that Apple does not publish such
- interpretations.
-
-
- Print Driver Calls
-
- Your printer driver handles the following calls:
-
- PrDefault ($0913)
-
- Description:
- Fills the fields of the specified print record with default values for the
- printer.
-
- Passed:
- PrintRecordHandle LONG Handle to the print record
-
- Returned:
- None
-
- Performs the following:
- o Validates that PrintRecordHandle is a handle and does nothing if not.
- o Determines the default values for the print record either through tables or
- calculations. The default values should take into account such things as
- paper size and orientation, print mode, printer type, etc.
- o Copies the default values to the print record specified by the
- PrintRecordHandle parameter.
-
- PrValidate ($0A13)
-
- Description:
- Checks the print record to see that it is valid for the currently installed
- printer driver.
-
- Passed:
- PrintRecordHandle LONG Handle to the print record
-
- Returned:
- ChangeFlag WORD Boolean; TRUE if the record is
- adjusted
-
- Performs the following:
- o Checks to see if the print record is from this particular driver.
- o If the print record is not from this driver, it uses the default values for
- this driver.
- o If the print record is from this driver, it makes any changes that might be
- needed (i.e., style, paper size, etc.).
-
- PrStlDialog ($0B13)
-
- Description:
- Performs a style dialog with the user.
-
- Passed:
- PrintRecordHandle LONG Handle to the print record
-
- Returned:
- ConfirmFlag WORD Boolean; TRUE if the dialog is
- confirmed
-
- Performs the following:
- o Conducts a style dialog with the user to determine the page dimensions and
- other information needed for page setup (the initial settings of the dialog
- are derived from the print record).
- o If the user confirms the dialog, the information from the dialog is saved
- in the specified print record, PrValidate is called, and the routine
- returns TRUE.
- o If the user cancels the dialog, the print record is left unchanged, and the
- routine returns FALSE.
-
- Note: The following are items typically found in printer style dialogs:
-
- o Paper Size (US Letter, US Legal, A4 Letter, B5 Letter, International
- Fanfold)
- o Printing Orientation (Landscape, Portrait)
- o Vertical Sizing (Normal, Intermediate, Condensed)
- o Special Effects:
- Font Effects (Font Substitution, Smoothing)
- Reduction or Enlargement
- Gaps or No Gaps between pages
-
- Every printer style dialog should have an OK button (default) and a Cancel
- button.
-
- Note: When calling other routines in your printer driver (like
- PrValidate), be sure to do so through the Tool Dispatcher ($E10000
- or $E10004) so any necessary patches have an opportunity to execute.
-
- PrJobDialog ($0C13)
-
- Description:
- Performs a job dialog with the user.
-
- Passed:
- PrintRecordHandle LONG Handle to the print record
-
- Returned:
- ConfirmFlag WORD Boolean; True if the dialog is
- confirmed
-
- Performs the following:
- o Conducts a job dialog with the user to determine the print quality, range
- of pages to print, and other specifications. The initial settings are
- derived from the previous PrJobDialog call (or initial default values)
- except the page range which is set to ALL, and the number of copies which
- is set to ONE.
- o If the user confirms the dialog, PrValidate is called, the print record is
- updated, and the routine returns TRUE.
- o If the user cancels the dialog, the print record is left unchanged, and the
- routine returns FALSE.
-
- Note: The following are items typically found in printer job dialogs:
-
- o Print Quality (Best, Faster, Draft, etc.)
- o Color option
- o Pages (All, Range)
- o Copies
- o Paper Source (paper cassette, manual feed)
-
- Every printer job dialog should have an OK button (default) and a Cancel
- button.
-
- Note: When calling other routines in your printer driver (like
- PrValidate), be sure to do so through the Tool Dispatcher ($E10000
- or $E10004) so any necessary patches have an opportunity to
- execute.
-
- PrPixelMap ($0D13)
-
- Description:
- Prints all or part of the specified pixel map.
-
- Passed:
- srcLocPtr LONG Pointer to the source LocInfo
- which contains the pointer to
- the pixel map.
- srcRectPtr LONG Pointer to the rectangle which
- encloses the pixel map to be
- printed.
- colorFlag WORD Boolean; FALSE if black and white,
- TRUE if color.
-
- Returned:
- None
- Performs the following:
- o Calls DevIsItSafe (port driver call) to verify that the port it functioning
- and it is safe to proceed. If it is not functioning, set the internal
- error code to $1302 (Port Not On) and return with an error status.
- o Saves the current grafPort.
- o Turns on the watch cursor to signal the user that it will take some time.
- o Clears the internal error code (default, if no errors occur).
-
- You can choose to print the pixel map in any convenient fashion; one
- convenient way is to allocate a new print record and call your normal printing
- routines. This method is outlined below.
-
- o Gets a new handle for a print record and set it to the defaults by calling
- PrDefault.
- o If colorFlag is set, change the style subrecord of the print record to
- reflect color printing.
- o Do any initialization that might be needed by the driver.
- o Determine the intersection of the two rectangles (rectangle pointed to by
- srcRectPtr and the pixel map's boundary rectangle from srcLocPtr) and if
- there is no intersection, then nothing is to be printed.
- o Print the pixel image which is within the intersection of the two
- rectangles.
- o Cause a page eject to occur on the printer.
- o Do any clean up that is needed.
- o Turn off the watch cursor by calling InitCursor (or restore the previous
- cursor using SetCursor).
- o Restore the grafPort by calling SetPort.
-
- PrOpenDoc ($0E13)
-
- Description:
- This routine initializes the things needed to open a document. In deferred
- mode, it establishes a grafPort and makes it the current port for printing.
-
- Passed:
- PrintRecordHandle LONG Handle to the print record
- PrinterPortPtr LONG Pointer to the grafPort, if
- desired, zero to allocate a new
- grafPort
- Returned:
- PrinterPortPtrRet LONG Pointer to the grafPort if the
- PrinterPortPtr was zero
-
- Performs the following:
- o Calls DevIsItSafe (port driver call) to verify that the port is functioning
- and it is safe to proceed.
- o Turns on the watch cursor to signal the user that it will take some time.
- o Validates the print record passed by calling PrValidate.
- o Clears the internal error code (default, if nothing happens).
- o Puts up a dialog indicating that printing is occurring (or preparing to
- print).
- o If the user needs a grafPort, create one and internally note that one was
- created (PrCloseDoc needs to know that one was created here).
- o Initializes parameters (i.e., page number, document number, etc.).
- o If deferred mode, create an initial page list (an array of handles to
- pictures) for recording pages. You can pick an arbitrary number to start
- with (like 20). This assumes spooling to memory; spooling to disk will
- obviously be different.
- o Do other initialization that might be needed to start a print job.
-
- Possible errors:
- portNotOn $1302 Indicates Port Not On
-
- PrCloseDoc ($0F13)
-
- Description:
- Closes the grafPort being used for printing. For immediate mode, this
- routine ends the printing job. For deferred mode, this routine ends the
- recording of the document to be printed.
-
- Passed:
- PrintGrafPortPtr LONG Pointer to the grafPort used for
- printing
-
- Returned:
- None
-
- Performs the following:
- o Checks that the last print driver call did not cause a Port Not On error.
- If the error occurred, do nothing and return.
- o Call ClosePort to close the printing grafPort.
- o If the driver allocated a grafPort in PrOpenDoc, disposes of it.
- o If in immediate mode, does what is needed to shut things down.
- o Takes down the information dialog box from PrOpenDoc.
-
-
- Possible errors:
- portNotOn $1302 Indicates Port Not On
- prBozo $13FF Someone unloaded the driver in
- the middle of the print loop
-
- PrOpenPage ($1013)
-
- Description:
- Begins a new page only if the page falls within the page range specified in
- the job subrecord.
-
- Passed:
- PrintGrafPortPtr LONG Pointer to the grafPort used for
- printing
- PageFramePtr LONG Pointer to the scaling parameter,
- zero for none.
- Returned:
- None
-
- Performs the following:
- o Looks at the driver's internal error value, and if an error has occurred,
- it returns without doing anything.
- o Increments the page number.
- o Calls SetPort to make the specified port the current port.
- o Initializes the port and zeroes the boundary rectangle so no actual drawing
- occurs.
- o If immediate mode, then do the following:
- If this page is to be printed, install immediate mode procedures by
- doing the following:
- o Create a procedure table (get the standard procedures from
- SetStdProcs).
- o Put pointers to your procedures into the table and call the
- QuickDraw II routine SetGrafProcs. This causes QuickDraw II calls
- to call your routines instead of drawing to the pixel map
- associated with the grafPort.
- o If deferred mode, then do the following:
- o If the current page is out of the page range, then return without
- doing anything further.
- o If the user passes his own PageFramePtr , then get it.
- o Open a picture by calling OpenPicture and adding its handle to the
- page list array described in PrOpenDoc.
- o Set the ClipRgn and VisRgn to the sizing framing rectangle specified
- by PageFramePtr , or if none was specified, to the default of rPage.
-
- Possible errors:
- portNotOn $1302 Indicates Port Not On
- prBozo $13FF Someone unloaded the driver in
- the middle of the print loop
-
- PrClosePage ($1113)
-
- Description:
- This signals the end of a page.
-
- Passed:
- PrintGrafPortPtr LONG Pointer to the grafPort used for
- printing
-
- Returned:
- None
-
- Performs the following:
- o Looks at the driver's internal error value and if a Port Not On error has
- occurred, it returns without doing anything.
- o If immediate mode, do the following:
- o If the current page is within the range of pages to be printed, then
- cause a form feed (unless no gap was specified).
- o If deferred mode, do the following:
- o If there was no picture generated, then do nothing and just return.
- o Restore the grafPort to the port saved in PrOpenPage.
- o Do a ClosePicture to close the picture.
-
- Possible errors:
- portNotOn $1302 Indicates Port Not On
- prBozo $13FF Someone unloaded the driver in
- the middle of the print loop
-
- PrPicFile ($1213)
-
- Description:
- Prints a picture file generated in deferred mode.
-
- Passed:
- PrintRecordHandle LONG Handle to the print record
- PrintGrafPortPtr LONG Pointer to the grafPort used for
- printing
- StatusRecPtr LONG Pointer to the printer status
- record
-
- Returned:
- None
-
- Performs the following:
- o Looks at the driver's internal error value and if a Port Not On error has
- occurred, it returns without doing anything.
- o If immediate mode, return without doing anything.
- o If deferred mode, then do the following:
- o If the error code is not zero (errors) then dispose of all the recorded
- page images.
- o Put up an information dialog indicating that printing is occurring.
- o Display a watch cursor (saving the current cursor first if you like).
- o If PrintGrafPortPtr is NIL, create one and make a note of it.
- o Call OpenPort to make the grafPort the current port.
- o If StatusRecPtr is NIL, use an internal one. This is to simplify your
- code; if the StatusRecPtr is NIL, you can reasonably choose not to use a
- status record at all, but this requires an extra code path.
- o Initialize the status record and the number of copies counter.
- o If the idle procedure pointer in the print record is NIL, point to an
- internal one. Again, as with the StatusRecPtr, you can choose to ignore
- idle procedures if no pointer is provided, but this requires an extra
- code path.
- o Do The Following For Each Copy:
- o Calculate the number of bands to print one page and initialize the
- page counter.
- o Do The Following For Each Page:
- o Call the idle procedure routine and initialize the band counter.
- o Get the handle to the picture associated with the current page.
- o Set the dirty flag in the status record to FALSE.
- o If manual paper feed, put up a dialog and wait for a response.
- o Do The Following For Each Band:
- o Call the idle procedure.
- o Calculate the band rectangle and update iCurBand with the
- current band number.
- o Call the idle procedure again.
- o Set the imaging flag in the status record to TRUE.
- o Call InitPort to reinitialize the port.
- o Adjust fields in the port to cause drawing into the band
- buffer.
- o Adjust fields in the location information field of the status
- record and calculate the sizing rectangle.
- o Calculate the boundary rectangle for the band and set the port
- rectangle to it.
- o Set the ClipRgn and the VisRgn to the sizing rectangle.
- o Initialize the band by filling it with white space.
- o Call DrawPicture to draw the picture into the band's
- rectangle.
- o Do whatever is needed to print the pixel image in the band's
- rectangle.
- o Clear the imaging flag.
- o Calculate the next band's position.
- o Increment the band's counter and loop back if not done.
- o If a vertical gap was specified, cause a form feed.
- o Increment the page count to the next page and loop back if not
- done.
- o Increment the number of copies counter and loop back if not done.
- o Free any buffers that you own and close the port.
- o Dispose of the information dialog that you put up.
- o Dispose of each picture in the picture list by calling KillPicture.
- o Dispose of the picture list itself.
- o Restore the cursor.
-
- Possible errors:
- portNotOn $1302 Indicates Port Not On
- prBozo $13FF Someone unloaded the driver in
- the middle of the print loop
-
- PrError ($1413)
-
- Description:
- Gets the error code from the last Print Manager call.
-
- Passed:
- None
-
- Returned:
- LastError WORD Result code from last Print
- Manager call
-
- Performs the following:
- o Gets the driver's internal error value (which was determined by the last
- driver call) and sets the return parameter LastError to it.
-
- Possible Errors:
- noError $0000
- PrAbort $0080 Indicates print job was aborted
- $1301 Indicates missing drivers
- $1302 Indicates Port Not On
- $1303 Indicates No Print Record
- $1306 Indicates PAP Connection Not
- Made
- $1307 Indicates Read/Write PAP Error
- $1308 Indicates Printer Connection
- Failed
- prBozo $13FF Someone unloaded the driver in
- the middle of the print loop
-
- PrSetError ($1513)
-
- Description:
- Sets the error value.
-
- Passed:
- ErrorNumber WORD Error number to be set
-
- Returned:
- None
-
- Performs the following:
- o Sets the driver's internal error value to the value of the passed
- ErrorNumber parameter.
-
- GetDeviceName ($1713)
- (also known as PrChanged)
-
- Description:
- Used as a communications tool between the printer driver and port driver.
-
- Passed:
- None
-
- Returned:
- None
-
- Performs the following:
- o Calls the port driver routine PrDevPrChanged with the printer name as
- input. This is necessary for drivers that work over AppleTalk. The name
- passed as the parameter to PrDevPrChanged should be what AppleTalk uses in
- an NBPLookup situation; for AppleTalk, such a name should follow Name
- Binding Protocol conventions.
-
- This routine will be called by the Print Manager when your driver is first
- loaded so a network port driver can find devices of your type.
- Applications should not make this call. When this routine will be called
- is not guaranteed; you can't use this as a substitute for a startup call.
-
- PrDriverVer ($2313)
-
- Description:
- Returns the version number of the currently installed printer driver.
-
- Passed:
- Wordspace WORD Space for results
-
- Returned:
- versionInfo WORD Printer driver's version number
-
- Performs the following:
- o Gets the internal version number of the printer driver and returns it on
- the stack at versionInfo.
-
- Note: The internal version number is stored major byte, minor byte
- (i.e., $0103 represents version 1.3)
-
- PrGetPrinterSpecs ($1813)
-
- Description:
- Returns the type of printer and the printer's characteristics.
-
- Passed:
- Wordspace WORD Space for results
- Wordspace WORD Space for results
-
- Returned:
- PrinterType WORD 0 = undefined
- 1 = ImageWriter or ImageWriter II
- 2 = ImageWriter LQ
- 3 = LaserWriter family
- (except IIsc)
- 4 = Epson
- $8001 = generic dot matrix printer
- $8003 = generic laser printer
- PrCharacteristics WORD Bits 15-2 = reserved, must be zero
- Bits 1-0: 00 = cannot determine
- 01 = black and white
- only
- 10 = color capable
-
- Performs the following:
- o Returns characteristics intrinsic for the printer being supported.
-
- The value returned for PrinterType should be the driver's iDev value.
-
- PrGetPgOrientation ($3813)
-
- Description:
- Returns the page orientation from a print record.
-
- Passed:
- Wordspace WORD Space for result
- PrintRecordHandle LONG Handle to the print record
-
- Returned:
- PgOrientation WORD Current page orientation:
- 0 = portrait
- 1 = landscape
-
- Performs the following:
- o Returns the page orientation from the current page setup information in the
- print record.
-
-
- Immediate Mode Procedures
-
- To print in the immediate mode, you need to install procedures which cause
- printing when you make QuickDraw II calls (as noted in PrOpenPage). This
- section describes the structure and parameters for these routines.
-
- The basic idea is that your driver replaces low-level QuickDraw II routines
- with pointers to your own routines. For example, when someone wants QuickDraw
- II to draw some text (say with DrawString), QuickDraw II calls your low-level
- routine to draw the text. You can then print the text instead.
-
- To install the immediate mode procedures, first create a procedure table for
- sixteen entries (16*4 bytes) and fill it with the standard procedures by
- calling SetStdProcs. Once you have the standard procedures, install the
- addresses of your replacement procedures into it and call SetGrafProcs.
- Installing your procedure addresses causes the appropriate QuickDraw II calls
- to call your procedures, which, in turn, perform the actual printing.
-
- The routines that need to be written are known as QuickDraw II "bottleneck
- procedures." For most dot-matrix printer drivers, the one of most concern
- when writing immediate mode procedures is StdText. If your target device has
- an alternate page imaging language, you may wish to print entirely in
- immediate mode. In this case, you want to intercept most of the bottleneck
- procedures. Apple IIgs Technical Note #34, Low-Level QuickDraw II Routines,
- contains information on how to install these procedures. The sample code
- which follows shows how to replace StdPixels and StdText.
-
- Example:
-
- ;*****************************************************************
- ;** Example of Immediate Mode Printer Procedures. **
- ;*****************************************************************
- Immedprocs Start
-
- SrcRect equ $DC
- SrcLocInfo equ $CC
- DrawVerb equ $38
- TextPtr equ $da
- TextLength equ $d8
- CharToDraw equ $d6
-
- ;------------------------------------------------------------------
- ;
- ; StdPixels Procedure (Prints Pixel maps)
- ;
- ;------------------------------------------------------------------
- Pixel Entry
-
- phb ;save data bank reg on stack
- phk ;get program bank reg.
- plb ;use as data bank reg.
-
- lda iPrErr ;get errors
- beq Continue ;branch if none
- brl ExitPixel ;branch if errors
-
- Continue anop
-
- ;This gets the source rectangle and stores it at PixelRect
- ldx #6
- MoveSrc lda SrcRect,x
- sta PixelRect,x
- dex
- dex
- bpl MoveSrc
-
- ;This gets the source LocInfo and stores it at PixelLoc
- ldx #16-2
- MoveLI lda SrcLocInfo,x
- sta PixelLoc,x
- dex
- dex
- bpl MoveLI
-
- pushlong #PixelLoc ;push pointer to LocInfo
- pushlong #PixelRect ;push pointer to rectangle
-
-
- ;++++++++++++++++++++++
- ; Insert code here to print a pixel map
- ; INPUT: PixelLoc LONG, Pointer to pixel LocInfo
- ; PixelRect LONG, Pointer to pixels BoundsRect
- ; SP->
- ;++++++++++++++++++++++
-
- Exitpixel lda #0 ;return with no errors
- clc
- plb ;restore data bank
- rtl ;return with long
-
- PixelLoc ds 16 ;pixel LocInfo
- PixelRect ds 8 ;pixel rectangle
-
- ;------------------------------------------------------------------
- ;
- ; StdText Procedure (Prints Standard Text)
- ;
- ;------------------------------------------------------------------
- StdText Entry
-
- phb ;save data bank reg on stack
- phk ;get program bank reg.
- plb ;use as data bank reg.
-
- pushlong #PenPos
- _GetPen ;current pen pos. -> PenPos
-
- ;++++++++++++++++++++++
- ; Insert Code Here to move the printers head to the corresponding
- ; PenPos position (if needed).
- ;++++++++++++++++++++++
-
- pushword #0 ;space for textwidth
- ;(for call to _TextWidth)
-
- lda DrawVerb ;get DrawVerb
- beq DoCar ;if DrawVerb=0 then DoCar
-
- cmp #1
- beq Dotext2 ;if DrawVerb=1 then Dotext2
- ;
- ;We get here if it's a "C" string (DrawVerb=2)
- ;
- DoCstring anop
- sep #$20
- longa off
- ;Search down through string looking for terminator to calc. length
- ldy #0
- KeepLooking lda [TextPtr],y
- beq TheEnd
- iny
- bra KeepLooking
- TheEnd rep #$20
- longa on
- lda TextPtr+2
- pha ;push the pointer to string
- lda Textptr
- pha
- phy ;push the length of sting
- bra Common
-
- ;
- ;We get here if it's just one character (DrawVerb=0)
- ;
- DoCar anop
- pushword #0
- tdc
- clc
- adc #CharToDraw ;calculate addr. of char.
- pha ;push addr. of character
- pushword #1 ;push length of one char.
- bra Common
-
- ;
- ;We get here if it's a string of text (DrawVerb=1)
- ;
- DoText2 anop
- lda TextPtr+2
- pha ;push pointer to the string
- lda Textptr
- pha
- lda TextLength
- pha ;push the strings length
- Common lda 5,s ;Dup the last 3 words of
- pha ;the stack (for _TextWidth)
- lda 5,s
- pha
- lda 5,s
- pha
- ;++++++++++++++++++++++
- ; Insert code here to print the text
- ;
- ; INPUT: TextPointer LONG, Pointer to text to print
- ; TextLength WORD, No. of bytes to print
- ; SP->
- ;++++++++++++++++++++++
- _TextWidth ;get the texts width (DH)
- pushword #0 ;set (DV)=0
- _Move ;move current pen location
-
- ExitText lda #0 ;return with no errors
- clc
- plb ;restore data bank
- rtl ;returnith long
-
- PenPos ds 4 ;pen position
- end
-
-
- Further Reference
- _____________________________________________________________________________
- o Apple IIgs Toolbox Reference, Volumes 1-3
- o Apple IIgs Technical Note #36, Port Driver Specifications
- o Apple IIgs Technical Note #90, 65816 Tips and Pitfalls
-
- PostScript is a registered trademark of Adobe Systems Incorporated.
-
-